/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package regulatoryInteractionsStats.yeast.bioJava;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;


import org.biojava3.alignment.SimpleGapPenalty;
import org.biojava3.alignment.SimpleSubstitutionMatrix;
import org.biojava3.alignment.SmithWaterman;
import org.biojava3.alignment.SubstitutionMatrixHelper;

import org.biojava3.alignment.template.Profile;

import org.biojava3.core.sequence.template.Sequence;
import regulatoryInteractionsStats.yeast.RegultoryInteractionSet;
import regulatoryInteractionsStats.yeast.YeastGene;
import regulatoryInteractionsStats.yeast.YeastGeneLibrary;
import utils.FileUtils;

/**
 *
 * @author jamie
 */
public class DoAlignments {

    private File sequenceFile = new File("/Users/jamie/Dropbox/monkeys/yeast/orf_coding.fasta");
    private TreeMap<String, String> sequences;
    private YeastGeneLibrary yeastGeneLibrary = new YeastGeneLibrary();
    private SequenceFactory seqFactory;
    private AlignableGeneFactory alinableGeneFactory;
    private ArrayList<AlignableGenePair> allPairs;
    private RegultoryInteractionSet ris = new RegultoryInteractionSet(yeastGeneLibrary);

    private File outputFile_full = new File("/Users/jamie/Documents/monkeys/alignments/full.txt");
    private File outputFile_stats = new File("/Users/jamie/Documents/monkeys/alignments/stats.txt");

    public DoAlignments() {
        System.out.println("getting sequences");
        sequences = getSequences(sequenceFile);
        System.out.println(sequences.size()+" sequences");
        System.out.println("making alignable gene factory");
        alinableGeneFactory = new AlignableGeneFactory();
        System.out.println("making alignable sequence factory");
        seqFactory = new SequenceFactory();
        System.out.println("getting all pairs");
        allPairs = getPairs();
        BufferedWriter writer_full = FileUtils.getBufferedWriter(outputFile_full);
        BufferedWriter writer_stats = FileUtils.getBufferedWriter(outputFile_stats);
        System.out.println(SubstitutionMatrixHelper.getNuc4_4().toString());
        try{
        for(AlignableGenePair p : allPairs){

//           SubstitutionMatrix<NucleotideCompound> matrix = SubstitutionMatrixHelper.getNuc4_4();
//           SequencePair<DNASequence, NucleotideCompound> pair = Alignments.getPairwiseAlignment(p.getG1().getSequence(), p.getG2().getSequence(), PairwiseSequenceAlignerType.LOCAL, new SimpleGapPenalty(), matrix);
//           System.out.printf("%n%s vs %s%n%s", p.getG1().getSequence(), p.getG2().getSequence(), pair);


           SmithWaterman sw;
           sw = new SmithWaterman();
           sw.setQuery(p.getG1().getSequence());
           sw.setTarget(p.getG2().getSequence());
           sw.setGapPenalty(new SimpleGapPenalty());
           sw.setSubstitutionMatrix(SubstitutionMatrixHelper.getNuc4_4());
           Profile profile = sw.getProfile();
           String statsString = p.getG1().getAccession()+":"+p.getG2().getAccession()+"\t"+sw.getScore()+"\t"+sw.getSimilarity()+"\n";
           String fullString = statsString+profile.toString()+"\n\n";
           writer_full.append(fullString);
           writer_stats.append(statsString);
           System.out.print(statsString);
        }
        writer_full.close();
        writer_stats.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }

    private TreeMap<String, String> getSequences(File sequenceFile) {
        TreeMap<String, String> seqHash = new TreeMap<String, String>();

        BufferedReader reader = FileUtils.getBufferedReader(sequenceFile);
        String line;
        String currentKey = null;
        boolean inSequence = false;
        try {

            while ((line = reader.readLine()) != null) {
                line.trim();

                if (line.startsWith(">")) {

                    String[] split = line.split(" ");
                    String accession = split[0].substring(1);
                    YeastGene yg = yeastGeneLibrary.getGeneByAccession(accession);
                    if(yg!=null && ris.getGenes().contains(yg.symbol)){
                        currentKey = accession;
                        seqHash.put(currentKey, "");
                        inSequence = true;
                    } else {
                        inSequence = false;
                    }

                } else if (inSequence) {
//                    System.out.println("inSequence "+seqHash.containsKey(currentKey));
                    String seq = seqHash.get(currentKey);
                    seqHash.put(currentKey, (seq + line));
                }

            }
            reader.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return seqHash;
    }

    private ArrayList<AlignableGenePair> getPairs() {
        ArrayList<AlignableGenePair> pairs = new ArrayList<AlignableGenePair>();
        List<String> keys = new ArrayList<String>();
        keys.addAll(sequences.keySet());
        for (int i = 0; i < keys.size(); i++) {
            String key1 = keys.get(i);
            
            for (int j = i+1; j < keys.size(); j++) {
                String key2 = keys.get(j);
                Sequence s1 = seqFactory.getSequence(key1, sequences.get(key1));
                Sequence s2 = seqFactory.getSequence(key2, sequences.get(key2));
                AlignableGene ag1 = alinableGeneFactory.getAlignableGene(key1, s1);
                AlignableGene ag2 = alinableGeneFactory.getAlignableGene(key2, s2);
//                System.out.println(key1+", "+key2);

                if(ag1.hasSequence() && ag2.hasSequence()){
                    AlignableGenePair p = new AlignableGenePair(ag1, ag2);
                    pairs.add(p);
//                    System.out.println(p.getG1().getAccession())
                }

            }


        }
       return pairs;
    }




}
